#include "ringqueue.hpp"
#include <string>
#include <unistd.h>
#include <ctime>
using namespace std;
template <class T>
struct ThreadData {
    ThreadData(const string& threadname, ringqueue<T> *ringqueue) 
        :_threadname(threadname)
        ,_ringqueue(ringqueue)
    {}
    string _threadname;
    ringqueue<T> *_ringqueue;
};

void *productor(void* args) {
    ThreadData<int> *data = static_cast<ThreadData<int>*>(args);
    while (true) {
        int val = rand() % 100 + 1;
        data->_ringqueue->push(val);
        cout << data->_threadname << " done data is: " << val << endl;
    }
    return nullptr;
}

void *consumer(void *args) {
    ThreadData<int> *data = static_cast<ThreadData<int>*>(args);
    while (true) {
        int val = 0;
        data->_ringqueue->Pop(&val);
        // sleep(1);
        cout << data->_threadname << " get a data: " << val << endl;
    }
    return nullptr;
}


int main() {
    srand((uint64_t)(time(nullptr)) ^ getpid() ^ pthread_self());
    pthread_t c[4], p[3];
    ringqueue<int> * rq = new ringqueue<int>(20);

    for (int i = 0; i < 4; i++) {
        ThreadData<int> *data = new ThreadData<int>("producer-" + to_string(i + 1), rq);
        pthread_create(&p[i], nullptr, productor, data);
    }

    for (int i = 0; i < 3; i++) {
        ThreadData<int> *data = new ThreadData<int>("consumer-" + to_string(i + 1), rq);
        pthread_create(&c[i], nullptr, consumer, data);
    }

    for (int i = 0; i < 4; i++) {
        pthread_join(p[i], nullptr);
    }
    for (int i = 0; i < 3; i++) {
        pthread_join(c[i], nullptr);
    }


    // // 创建线程
    // pthread_create(&p, nullptr, productor, rq);
    // pthread_create(&c, nullptr, consumer,rq);

    // pthread_join(p, nullptr);
    // pthread_join(c, nullptr);

    return 0;
}